package com.yoso.starter.boot.util.file;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.yoso.starter.boot.util.file.param.WatermarkDO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * PDF文件水印处理
 * @author shizejin
 * @date 2024/12/02
 */
@Slf4j
public class PDFWatermarkHandler extends AbstractWatermarkHandler {

    @SneakyThrows
    public static void main(String[] args) {
        PDFWatermarkHandler pdfWatermarkHandler = new PDFWatermarkHandler();
        WatermarkDO watermarkDO = new WatermarkDO();
        watermarkDO.setWatermark("仅用于光大理财账户管理模块");
//        watermarkDO.setWatermark("禁止抄袭");
        watermarkDO.setFontSize(40);
        watermarkDO.setSrcPath("D:\\yoso\\dev\\temp\\【托管账户回执单】工商银行北京分行-光大理财阳光碧乐活78号理财产品.pdf");
        watermarkDO.setDestPath("D:\\yoso\\dev\\temp\\2.pdf");
        pdfWatermarkHandler.appendWatermark(watermarkDO);
    }

    /**
     * 给文件添加水印
     *
     * @param watermarkDO
     * @author shizejin
     * @date 2024/11/26
     */
    @Override
    public void appendWatermark(WatermarkDO watermarkDO) throws IOException {
        int lineHeight = watermarkDO.getLineHeight();
        int lineNum = 10;
        int repeatInline = watermarkDO.getRepeatInline();
        int fontsize = watermarkDO.getFontSize();
        int rotation = watermarkDO.getRotation();
        int lineSplitLength = watermarkDO.getLineSplitLength();
        try {
            StringBuilder watermark = new StringBuilder(watermarkDO.getWatermark());
//            一行水印重复n次
            for (int i = 0; i < repeatInline - 1; i++) {
//                同一行水印之间加入n个空格
                for (int j = 0; j < lineSplitLength; j++) {
                    watermark.append(" ");
                }
                watermark.append(watermarkDO.getWatermark());
            }

            // 创建PdfReader对象读取现有的PDF文件
            com.itextpdf.text.pdf.PdfReader reader = new PdfReader(watermarkDO.getSrcPath());
            // 创建PdfStamper对象用于修改PDF文件
            PdfStamper stamper = new PdfStamper(reader, FileUtil.getOutputStream(watermarkDO.getDestPath()));
            // 获取总页数
            int pageNums = reader.getNumberOfPages();
            // 设置字体和透明度
            BaseFont baseFont = BaseFont.createFont("SimSun.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, false,
                    IoUtil.readBytes(getFountInputStream()), null);
            // 循环遍历每一页并添加水印
            for (int pageNum = 1; pageNum <= pageNums; pageNum++) {
                // 获取页面尺寸
                Rectangle pageSize = reader.getPageSizeWithRotation(pageNum);
                float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
                float y = (pageSize.getTop() + pageSize.getBottom()) / 2;
                // 获取内容字节流
                // 水印图片设置在内容之上，之下用getUnderContent
                PdfContentByte content = stamper.getOverContent(pageNum);
                PdfGState gs = new PdfGState();
                gs.setFillOpacity(watermarkDO.getOpacity()); // 设置透明度
                // 获取内容字节流
                content.saveState();
                content.setGState(gs);
                drawWatermark(content, baseFont, fontsize, watermark.toString(), x, y, rotation);
                for (int line = 1; line <= lineNum; line++) {
//                    向上移动
                    float xMove = x - (float) (Math.tan(45) * lineHeight * line);
                    float yMove = y + lineHeight * line;
                    drawWatermark(content, baseFont, fontsize, watermark.toString(), xMove, yMove, rotation);
//                    向下移动
                    float xMove2 = x + (float) (Math.tan(45) * lineHeight * line);
                    float yMove2 = y - lineHeight * line;
                    drawWatermark(content, baseFont, fontsize, watermark.toString(), xMove2, yMove2, rotation);
                }
                content.restoreState();
            }
            // 关闭PdfStamper对象
            stamper.close();
            reader.close();
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取中文字体流（宋体）
     *
     * @return {@link InputStream }
     * @author shizejin
     * @date 2024/12/04
     */
    private InputStream getFountInputStream() {
        try {
            ClassPathResource resource = new ClassPathResource("ttf/SimSun.ttf");
            return resource.getInputStream();
        } catch (IOException e) {
            log.error("获取水印字体失败");
            throw new RuntimeException(e);
        }
    }

    /**
     * 加水印
     *
     * @param content   当前页
     * @param baseFont  字体
     * @param fontSize  字体大小
     * @param watermark 水印内容
     * @param x         水印横坐标
     * @param y         水印纵坐标
     * @param rotation  旋转角度
     * @author shizejin
     * @date 2024/12/04
     */
    private static void drawWatermark(PdfContentByte content, BaseFont baseFont, int fontSize, String watermark, float x, float y, float rotation) {
        content.beginText();
        content.setFontAndSize(baseFont, fontSize);
        content.showTextAligned(Element.ALIGN_CENTER, watermark, x, y, rotation);
        content.endText();
    }

}
